package com.sparrow.common.util;


import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.io.CharSource;
import com.google.common.io.Files;
import com.sparrow.common.stringmatch.ac.ACAutomaton;
import com.sparrow.common.stringmatch.trie.Trie;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.nio.charset.Charset;
import java.util.LinkedList;
import java.util.List;

/**
 * 敏感词工具类,使用Trie（字典树）算法
 * <p>
 * 
 * 根据敏感词字库生成敏感词树,待验证字符从根节点开始寻找,如果有匹配到的完整的敏感词子树就表示有敏感词
 * 
 * @author shengbao.Liu
 * @email 646406929@qq.com
 * @time 2016年7月27日 上午11:27:00
 * 
 */
public class WordUtil {

	private static Logger logger = LoggerFactory.getLogger(WordUtil.class);

	private static final String filter_text_path = "config/filter_text.json";

	private static volatile ACAutomaton ac;

	public static void checkLoad() {
		if (ac == null) {
			synchronized (WordUtil.class) {
				if (ac == null) {
					load();
				}
			}
		}
	}

	/**
	 * 检查是否存在敏感词
	 * 
	 * @param content
	 * @return
	 */
	public static boolean isMatch(String content) {
		checkLoad();
		return match(content).length() > 0;
	}

	/**
	 * 检查敏感词
	 * 
	 * @param content
	 * @return
	 */
	private static String match(String content) {
		return ac.matchFirst(content);
	}

	public static List<String> loadWords() {
		try {
			File file = FileUtil.getFile(filter_text_path);
			CharSource charSource = Files.asCharSource(file, Charset.forName("utf8"));
			String jsonStr = charSource.read();
			ObjectMapper objectMapper = new ObjectMapper();
			JsonNode jsonNode = objectMapper.readTree(jsonStr);
			//获取name字段值
			JsonNode filterNode = jsonNode.get("filter");
			if (filterNode == null || !filterNode.isArray()) {
				throw new IllegalArgumentException("JSON 中缺少 'filter' 数组");
			}
			List<String> wordList = new LinkedList<>();
			for (JsonNode subNode : filterNode) {
				String value = subNode.asText();
				wordList.add(value);
			}
			return wordList;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}

	}

	public static void load() {
		logger.info("载入敏感词~~~~~~");
		try {
			long start = System.currentTimeMillis();
			List<String> words = loadWords();
			ac = new ACAutomaton();
			ac.load(words);
			long cost = System.currentTimeMillis() - start;
			logger.info("载入敏感词库成功 cost:{}", cost);
		} catch (Throwable e) {
			logger.error("加载屏蔽字库错误：{}", filter_text_path, e);
			e.printStackTrace();
		}
	}

}
